<?php

namespace app\common\service;

use app\common\model\Dept;
use app\common\model\Role;
use app\common\model\RoleUser;
use app\common\model\User;
use app\common\model\UserDeptAuth;
use app\common\exception\ApiException;
use think\facade\Db;

class UserService
{
    
    
    /**
     * 获取Token
     * @return array|mixed
     * @throws ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getToken()
    {
        $token = request()->header('XX-TOKEN', '');
        $deviceType = request()->header('XX-DEVICE-TYPE', '');
        
        if (empty($deviceType)) {
            throw new ApiException('尚未登陆', 10001);
        }
        
        if (empty($token)) {
            throw new ApiException('尚未登陆', 10001);
        }
        
        $userToken = Db::name('user_token')->where('token', $token)->where('device_type', $deviceType)->find();
        if (empty($userToken)) {
            throw new ApiException('尚未登陆', 10001);
        }
        
        return $userToken;
    }
    
    /**
     * 创建Token
     * @param $userId
     * @return mixed|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function generateToken($userId = 0)
    {
        $deviceType = request()->header('XX-DEVICE-TYPE', '');
        
        $userTokenQuery = Db::name('userToken')->where('user_id', $userId)->where('device_type', $deviceType);
        $findUserToken = $userTokenQuery->find();
        $expireTime = date('Y-m-d H:i:s', time() + 24 * 3600 * 180);
        $token = md5(uniqid()) . md5(uniqid());
        
        if (empty($findUserToken)) {
            Db::name('userToken')->insert([
                'token' => $token,
                'user_id' => $userId,
                'expire_time' => $expireTime,
                'create_time' => date('Y-m-d H:i:s'),
                'device_type' => $deviceType
            ]);
        } else {
            if ($findUserToken['expire_time'] > time() && !empty($findUserToken['token'])) {
                $token = $findUserToken['token'];
            } else {
                Db::name('userToken')->where('user_id', $userId)->where('device_type', $deviceType)->update([
                    'token' => $token,
                    'expire_time' => $expireTime,
                    'create_time' => date('Y-m-d H:i:s')
                ]);
            }
        }
        return $token;
    }
    
    
    
    /**
     * 获取用户
     * @return array|mixed|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function get()
    {
        // $token = request()->header('XX-TOKEN', '');
        // return (new User())->where('token', $token)->with(['dept'])->find();
        return User::where('id', '=', self::getToken()['user_id'])->with(['dept'])->find();
    }
    
    /**
     * 获取用户ID
     * @return false|mixed
     */
    public static function getId()
    {
        return (int)User::where('id', '=', self::getToken()['user_id'])->value('id');
    }
    
    /**
     * 获取单个字段
     * @param $field 字段
     * @return false|mixed
     */
    public static function getValue($field = '')
    {
        return User::where('id', '=', self::getToken()['user_id'])->value($field);
    }
    
    /**
     * 修改个人信息
     * @param $data
     * @param $where
     * @return User|false|int|\think\db\Query
     * @throws \think\db\exception\DbException
     */
    public static function update($data = [], $where = [])
    {
        if (empty($data)) {
            return false;
        }
        $where[] = ['id', '=', self::getToken()->user_id];
        return User::where($where)->update($data);
    }
    
    /**
     * 获取权限规则
     * @param $userId 用户ID
     * @return array
     */
    public static function getRules($userId = 0): array
    {
        if ($userId === 1) {
            // 总后台超级管理员
            return ['*'];
        }
        $roleIds = self::getRoleIds($userId);
        $rules = Role::where('id', 'in', $roleIds)->column('rules');
        $result = [];
        foreach ($rules as $value) {
            if (!empty($value)) {
                array_push($result, ...explode(",", $value));
            }
        }
        return array_unique(array_map(fn($item) => strtolower($item), $result));
    }
    
    /**
     * 获取角色ID
     * @param $userId
     * @return array
     */
    public static function getRoleIds($userId = 0)
    {
        if($userId === 1){
            return [1];
        }
        return RoleUser::where('user_id', $userId)->column('role_id');
    }
    
    /**
     * 获取部门
     * @return array|mixed|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getDept()
    {
        $deptId = self::getValue('dept_id');
        return Dept::where('id', $deptId)->find();
    }

    /**
     * 获取用户数据权限
     * @param $userId
     * @return array|string[]
     */
    public static function getRoleDataAuth($userId = 0)
    {
        $return = [];
        if ($userId > 0) {
            $returns = UserDeptAuth::where('user_id', $userId)->value('dept_ids');
            if (!empty($returns)) {
                $return = explode(',', $returns);
            }
        }
        return $return;
    }
}